
/*
   - * =====================================================================================
   - *
   - *       Filename:  main.cc
   - *
   - *    Description:
   - *
   - *        Version:  1.0
   - *        Created:  02/27/19 11:40:46
   - *       Revision:  none
   - *       Compiler:  gcc
   - *
   - *         Author:  liushuyong (), shuyong1999@163.com
   - *        Company:  shuyong
   - *
   - * =====================================================================================
   - */
#include <iostream>
#include <sstream>
#include <string>
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <execinfo.h>
#include <fstream>

#include "CommFunc.h"
#include "CommHead.h"

#include "gflags/gflags.h"
#include "BrpcServer.h"

using std::string;
using std::cout;
using std::endl;
using namespace google;

//brpc
DEFINE_int32(port, 8802, "TCP Port of this server");
DEFINE_int32(idle_timeout_s, 10, "Connection will be closed if there is no request");
DEFINE_int32(rpc_max_concurrency, 24, "Connection with server in one client");
DEFINE_int32(num_threads, 20, "bthread number");
DEFINE_string(pid_file, "logs/tts-service_pid.log", "");
DEFINE_string(models_folder, "", "tts engine model path.");
DEFINE_int32(max_text_len, 1024, "max text length the service could accept");

//glog
//DEFINE_string(log_dir, "/tmp/TTSService", "");
//DEFINE_int32 (logtostderr, false, "log seconds");  //是否将日志输出到stderr，而非文件
//DEFINE_int32(logbufsecs, 0, "log seconds"); ////日志最多缓存的秒数
//DEFINE_int32(max_log_size, 1024, "max log size");   //最大日志大小（MB）
//DEFINE_int32(logbuflevel, -1, "log buf level"); //缓存日志的最低等级 , -1表示不缓存  google::INFO
//DEFINE_int32 (stop_logging_if_full_disk, true, "stop log");  //磁盘满停止记录日志

//TTS Service
DEFINE_int32(reqid_clean_interval, 3, "check reqid cache interval to clean timeout itmes");
DEFINE_int32(reqid_cache_timeout, 30, "the timeout of reqid keeping in cache");
DEFINE_int32(max_sessions_count, 200, "max sessions count the service could accept");
DEFINE_bool(use_repair_tools, true, "use repair tools from config or environment");
DEFINE_bool(isDebugInfo, true, "return debug info ");

static void printParams();
static void saveCoreDump(int sig);
static void saveBackTrace(int sig);
static void coreDumpHandle(const char* data, int size);

#define VERSION "H2-V1.0.1"

BrpcServer* pHttpServer = NULL;

int main(int argc, char** argv) {
    cout << "TTSService start..." << std::endl;
    //glog
    FLAGS_colorlogtostderr = true;  //设置输出到屏幕的日志显示相应颜色
    FLAGS_logbufsecs = 0;   //日志最多缓存的秒数, 实时输出
    FLAGS_stop_logging_if_full_disk = true;
    FLAGS_logbuflevel = -1; //缓存日志的最低等级
    google::SetVersionString(VERSION);  //软件版本
    google::SetUsageMessage("Usage : ./tts_server ");   //使用手册

    do {
        //gflag
        //从配置文件读取参数  //google::ParseCommandLineFlags(&argc, &argv, true);
        google::SetCommandLineOption("flagfile", "/root/tts-service.conf");
        printParams();
        //glog   INFO   WARNING  ERROR  FATAL
        google::InitGoogleLogging(argv[0]);
        google::SetLogDestination(google::GLOG_INFO, FLAGS_log_dir.c_str());    //google::SetLogDestination(google::GLOG_ERROR, FLAGS_log_dir.c_str());
        google::SetStderrLogging(google::GLOG_INFO);    //c高于 google::ERROR 的日志同时输出到屏幕
        google::InstallFailureSignalHandler();
        google::InstallFailureWriter(&coreDumpHandle);
        LOG(INFO) << "TTSService Start..." << endl;
        //1. create Http server
        BrpcServer::loadResouce(FLAGS_models_folder);
        pHttpServer = new BrpcServer();
        //2. start
        LOG(INFO) << "Start HttpServer" << endl;
        pHttpServer->start();
        //3. stop
        LOG(INFO) << "Stop HttpServer" << endl;
        pHttpServer->stop();
        //4. release
        LOG(INFO) << "Release HttpServer" << endl;
        delete pHttpServer;
        LOG(ERROR) << "TTSService End" << endl;
        google::ShutDownCommandLineFlags();
        google::ShutdownGoogleLogging();    //防止内存溢出
    } while (0);

    return 0;
}

static void coreDumpHandle(const char* data, int size) {
    std::ofstream fs("tts_coredump.log", std::ios::app);
    std::string str = std::string(data, size);
    fs << str;
    fs.close();
    LOG(ERROR) << str;
}

static void printParams() {
    cout << "port=" << FLAGS_port << endl;
    cout << "idle timeout=" << FLAGS_idle_timeout_s << endl;
    cout << "rpc_max_concurrency=" << FLAGS_rpc_max_concurrency << endl;
    cout << "num_threads=" << FLAGS_num_threads << endl;
    cout << "pid_file=" << FLAGS_pid_file << endl;
    cout << "log_dir=" << FLAGS_log_dir << endl;
    cout << "models_folder=" << FLAGS_models_folder << endl;
    cout << "max_text_len=" << FLAGS_max_text_len << endl;
    cout << "max_log_size=" << FLAGS_max_log_size << endl;
    cout << "reqid_clean_interval=" << FLAGS_reqid_clean_interval << endl;
    cout << "reqid_cache_timeout=" << FLAGS_reqid_cache_timeout << endl;
    cout << "max_sessions_count=" << FLAGS_max_sessions_count << endl;
    cout << "use_repair_tools=" << FLAGS_use_repair_tools << endl;
}
